package dawn.jxufe.community.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * @author dawn21
 * @version 1.0
 * @date 2022/8/3 20:14
 * @component
 */
// @Component // 加入bean
// @Aspect // 切面组件
public class AlphaAspect {

    // 第一件事情：定义切点。哪些bean，哪些方法是处理的目标。
    // 第一个*方法的返回值，什么返回值都行。
    // service包下的所有类。
    // 所有的方法。
    // 所有的参数。-> 都要处理。
    @Pointcut("execution(* dawn.jxufe.community.service.*.*(..))")
    public void pointcut(){

    }
    // 第二件事情：定义通知。
    // advice: 在target什么地方干什么。
    // 解决明确的问题。
    // 定义5种通知：在连接点的开始、连接点的结束做什么事情；
    // 返回数据后做什么事情；抛异常时做什么事情；连接点前后都要做什么事情。
    @Before("pointcut()") // 在 切入点的开始 处理事情，例如：输出、记录日志。
    public void before() {
        System.out.println("before");
    }

    @After("pointcut()") // 在 切入点的结束 处理事情，例如：输出、记录日志。
    public void after() {
        System.out.println("after");
    }

    @AfterReturning("pointcut()") // 在 切入点返回值之后 处理事情，例如：输出、记录日志。
    public void afterReturning() {
        System.out.println("afterReturning");
    }

    @AfterThrowing("pointcut()") // 在 切入点抛异常时 处理事情，例如：输出、记录日志。
    public void afterThrowing() {
        System.out.println("afterThrowing");
    }

    @Around("pointcut()") // 在 切入点前后 处理事情，例如：输出、记录日志。
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable{ // 连接点，织入的部位。
        System.out.println("around before");
        Object obj = joinPoint.proceed(); // 调用要处理的原始的目标组件的方法。
        System.out.println("around after");
        return obj; // 返回目标组件的返回值。
    } // 程序执行时，会执行代理对象，这个逻辑会被织入到代理对象，用来代替原始对象。

}
